﻿using Slock.Components;
using Slock.GameObjects;
using Slock.Utility;
using Microsoft.Xna.Framework;

namespace Slock.Generation
{
    /// <summary>
    /// Generates flat plane worlds
    /// </summary>
    public class FlatPlaneGenerator : IBlockFactory
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="world"></param>
        /// <param name="dimension"></param>
        /// <param name="terrains"></param>
        public void GenerateWorld(World world, Point3 dimension, out TerrainPatch[,,] terrains)
        {
            terrains = new TerrainPatch[dimension.X, dimension.Y, dimension.Z];

            // Fill out our patches with a simple plane
            for (int x = -dimension.X / 2; x < dimension.X / 2; x++)
            {
                for (int y = -dimension.Y / 2; y < dimension.Y / 2; y++)
                {
                    for (int z = -dimension.Z; z < 0; z++)
                    {
                        TerrainPatch patch = new TerrainPatch(world, new Point3(x + dimension.X / 2, y + dimension.Y / 2, z));

                        patch.Position = new Vector3
                        (
                            x * WorldInfo.Terrain_Patch_Dimension.X * WorldInfo.BLOCK_SIZE, 
                            y * WorldInfo.Terrain_Patch_Dimension.Y * WorldInfo.BLOCK_SIZE, 
                            z * WorldInfo.Terrain_Patch_Dimension.Z * WorldInfo.BLOCK_SIZE
                        );

                        patch.Position += new Vector3(WorldInfo.BLOCK_SIZE / 2.0f, WorldInfo.BLOCK_SIZE / 2.0f, WorldInfo.BLOCK_SIZE / 2.0f);

                        FillPatch(ref patch);
                        patch.BuildGeometry(true);

                        terrains[x + dimension.X / 2, y + dimension.Y / 2, z + dimension.Z] = patch;
                    }
                }
            }
        }

        /// <summary>
        /// A small helper method for filling an individual patch 
        /// </summary>
        /// <param name="patch"></param>
        private void FillPatch(ref TerrainPatch patch)
        {
            var patchSize = WorldInfo.Terrain_Patch_Dimension;

            for (int x = 0; x < patchSize.X; x++)
            {
                for (int y = 0; y < patchSize.Y; y++)
                {
                    for (int z = 0; z < patchSize.Z; z++)
                    {
                        patch.UpdateBlockPosition(x, y, z, BlockTypes.Dirt);
                    }
                }
            }
        }

    }
}
